package com.ht.WeNas.utils;

import com.ht.WeNas.data.vo.ResPage;

import java.nio.file.Path;
import java.util.Arrays;
import java.util.Deque;
import java.util.LinkedList;
import java.util.List;
import java.util.function.Function;

public class VirtualPageUtil {
    /**
     * 通过路径近似的方式，将path数组转换为虚拟分页
     *
     * @param pathList       需要被转换的数组
     * @param virtualCurrent 页码
     * @param virtualSize    单页大小
     * @param minBreakSize   最小打断字符数
     * @return 转换后的虚拟分页
     */
    public static List<ResPage<String>> pathToVirtualPage(
            List<Path> pathList,
            int[] virtualCurrent,
            int[] virtualSize,
            int minBreakSize
    ) {
        return toVirtualPage(pathList,
                virtualCurrent,
                virtualSize,
                (list -> FileNameGrouper.groupFilesBySimilarity(list, minBreakSize)),
                MyPathUtil::toPathString
        );
    }

    /**
     * 将数组转换为虚拟分页
     *
     * @param list           需要被转换的数组
     * @param virtualCurrent 页码
     * @param virtualSize    单页大小
     * @param groupFn        将数组分组的方法
     * @param convertor      将元素进行转换
     */
    public static <T, D> List<ResPage<T>> toVirtualPage(
            List<D> list,
            int[] virtualCurrent,
            int[] virtualSize,
            Function<List<D>, List<List<D>>> groupFn,
            Function<D, T> convertor
    ) {
        List<List<D>> grouped = groupFn.apply(list);
        Deque<Integer> currentStack = Arrays.stream(virtualCurrent)
                .collect(LinkedList::new, LinkedList::add, LinkedList::addAll);

        Deque<Integer> pageSizeStack = Arrays.stream(virtualSize)
                .collect(LinkedList::new, LinkedList::add, LinkedList::addAll);
        return grouped.stream().filter(item -> !item.isEmpty()).map(l -> {
            Integer current = currentStack.peekFirst();
            Integer pageSize = pageSizeStack.peekFirst();
            if (current == null) current = 0;
            if (pageSize == null) pageSize = 0;
            if (currentStack.size() > 1) {
                currentStack.pollFirst();
            }
            if (pageSizeStack.size() > 1) {
                pageSizeStack.pollFirst();
            }
            return ResPage.fromList(current, pageSize, l.stream().map(convertor).toList());
        }).toList();
    }

    /**
     * 将数组转换为虚拟分页
     *
     * @param list           需要被转换的数组
     * @param virtualCurrent 页码
     * @param virtualSize    单页大小
     * @param groupFn        将数组分组的方法
     */
    public static <T> List<ResPage<T>> toVirtualPage(
            List<T> list,
            int[] virtualCurrent,
            int[] virtualSize,
            Function<List<T>, List<List<T>>> groupFn
    ) {
        return toVirtualPage(list, virtualCurrent, virtualSize, groupFn, (i) -> i);
    }
}
